using System;
using System.Collections.Generic;
using System.Linq;
using DG.Tweening;
using UnityEngine;
using UnityEngine.UI;

namespace Core.Extension
{
    public static class UnityExtension
    {
        public static void SetHide(this Transform transform)
        {
            transform.localScale = Vector3.zero;
        }

        public static void SetShow(this Transform transform)
        {
            transform.localScale = Vector3.one;
        }

        public static void SetHide(this GameObject gameObject)
        {
            SetHide(gameObject.transform);
        }

        public static void SetShowState(this Transform transform, bool state)
        {
            if (state)
            {
                transform.SetShow();
            }
            else
            {
                transform.SetHide();
            }
        }

        public static void SetShowState(this GameObject gameObject, bool state)
        {
            gameObject.transform.SetShowState(state);
        }

        /// <summary>
        /// 显示对象
        /// </summary>
        /// <param name="gameObject"></param>
        public static void SetShow(this GameObject gameObject)
        {
            SetShow(gameObject.transform);
        }

        public static T GetCom<T>(this Transform transform, string fullPath = null) where T : Component
        {
            T ret;
            if (string.IsNullOrEmpty(fullPath))
            {
                ret = transform.GetComponent<T>();
            }
            else
            {
                ret = transform.Find(fullPath).GetComponent<T>();
                if (ret == null)
                    Debug.LogError($"{transform.name} not {typeof(T).ToString()} component!");
            }

            return ret;
        }

        public static T GetCom<T>(this GameObject gameObject, string fullPath = null) where T : Component
        {
            return gameObject.transform.GetCom<T>(fullPath);
        }

        /// <summary>
        /// 为对象绑定点击事件
        /// </summary>
        /// <param name="gameObject"></param>
        /// <param name="action"></param>
        /// <param name="normalEffectAudio">是否使用默认的点击音效</param>
        public static void BindEvent(this GameObject gameObject, Action action, bool normalEffectAudio = true)
        {
            if (gameObject.GetCom<Button>() == null)
            {
                if (gameObject.GetComponent<Image>() == null && gameObject.GetComponent<EmptyRaycast>() == null)
                {
                    gameObject.AddComponent<EmptyRaycast>();
                }

                gameObject.AddComponent<Button>();
            }

            gameObject.GetCom<Button>().BindEvent(action, normalEffectAudio);
        }

        /// <summary>
        /// 为对象绑定点击事件
        /// </summary>
        public static void BindEvent(this Transform transform, Action action, bool normalEffectAudio = true)
        {
            transform.gameObject.BindEvent(action, normalEffectAudio);
        }

        /// <summary>
        /// 为对象绑定点击事件
        /// </summary>
        public static void BindEvent(this Button button, Action action, bool normalEffectAudio = true)
        {
            if (button != null)
            {
                button.onClick.AddListener(() =>
                {
                    if (normalEffectAudio)
                    {
                        AudioMgr.Ins.PlaySound("btnClick", EAudioSuffix.wav, 0.35f);
                    }

                    action?.Invoke();
                });
            }
            else
            {
                throw new NullReferenceException("BindEvent button is null");
            }
        }

        /// 设置X坐标
        public static void SetX(this Transform transform, float value)
        {
            transform.position = new Vector3(value, transform.position.y, transform.position.z);
        }

        /// 设置Y坐标
        public static void SetY(this Transform transform, float value)
        {
            transform.position = new Vector3(transform.position.x, value, transform.position.z);
        }

        /// 设置Z坐标
        public static void SetZ(this Transform transform, float value)
        {
            transform.position = new Vector3(transform.position.x, transform.position.y, value);
        }

        /// 设置私有X坐标
        public static void SetLocalPosX(this Transform transform, float value)
        {
            transform.localPosition = new Vector3(value, transform.localPosition.y, transform.localPosition.z);
        }

        /// 设置私有Y坐标
        public static void SetLocalPosY(this Transform transform, float value)
        {
            transform.localPosition = new Vector3(transform.localPosition.x, value, transform.localPosition.z);
        }

        /// 设置私有Z坐标
        public static void SetLocalPosZ(this Transform transform, float value)
        {
            transform.localPosition = new Vector3(transform.localPosition.x, transform.localPosition.y, value);
        }

        public static void SetXY(this Transform transform, float valueX, float valueY)
        {
            transform.position = new Vector3(valueX, valueY, transform.position.z);
        }

        public static void SetYZ(this Transform transform, float valueY, float valueZ)
        {
            transform.position = new Vector3(transform.position.x, valueY, valueZ);
        }

        public static void SetXZ(this Transform transform, float valueX, float valueZ)
        {
            transform.position = new Vector3(valueX, transform.position.y, valueZ);
        }

        public static void SetLocalXY(this Transform transform, float valueX, float valueY)
        {
            transform.localPosition = new Vector3(valueX, valueY, transform.localPosition.z);
        }

        public static void SetLocalYZ(this Transform transform, float valueY, float valueZ)
        {
            transform.localPosition = new Vector3(transform.localPosition.x, valueY, valueZ);
        }

        public static void SetLocalXZ(this Transform transform, float valueX, float valueZ)
        {
            transform.localPosition = new Vector3(valueX, transform.localPosition.y, valueZ);
        }

        /// 获取当前所有的碰撞对象
        public static List<Collider2D> GetAllContacts(this Collider2D collider2D)
        {
            if (collider2D == null) return null;
            Collider2D[] contacts = new Collider2D[500];
            collider2D.GetContacts(contacts);
            var result = contacts.ToList();
            result.RemoveAll(item => item == null);
            return result;
        }

        public static void SetNativeSize(this SpriteRenderer sr)
        {
            sr.size = sr.sprite.bounds.size;
        }

        /// <summary>
        /// 当对象销毁时
        /// </summary>
        /// <param name="gameObject"></param>
        /// <param name="cb"></param>
        public static void OnDestroy(this GameObject gameObject, Action cb)
        {
            var observableLife = gameObject.GetComponent<ObservableLife>();
            if (gameObject.GetComponent<ObservableLife>() == null)
                observableLife = gameObject.AddComponent<ObservableLife>();
            observableLife._OnDestroy += delegate { cb?.Invoke(); };
        }

        /// <summary>
        /// 当对象被禁用时
        /// </summary>
        /// <param name="gameObject"></param>
        /// <param name="cb"></param>
        public static void OnDisable(this GameObject gameObject, Action cb)
        {
            var observableLife = gameObject.GetComponent<ObservableLife>();
            if (gameObject.GetComponent<ObservableLife>() == null)
                observableLife = gameObject.AddComponent<ObservableLife>();
            observableLife._OnDisable += delegate { cb?.Invoke(); };
        }
    }
}